<?php

declare(strict_types=1);

namespace App\Repositories\Gashapon;

use App\Exceptions\BasicException;
use App\Models\MainDB\Gashapon\Pool as Model;
use App\Models\MainDB\Gashapon\PoolTemplate;
use App\Traits\Singleton;
use Illuminate\Database\Eloquent\Collection;

class PoolRepository
{
    use Singleton;

    public function getIndependentType()
    {
        return Model::INDEPENDENT_TYPE;
    }

    public function getNoviceType()
    {
        return Model::NOVICE_TYPE;
    }

    public function getDefaultType()
    {
        return Model::DEFAULT_TYPE;
    }

    public function allowPoolsType()
    {
        return Model::query()->pluck('type');
    }

    public function getUserPool($user, bool $fail = false, bool $lock = false)
    {
        $allowPoolsType  = $this->allowPoolsType();
        $independentUser = IndependentUserRepository::getInstance()->getUserPoolType($user->id);
        if ($independentUser && in_array($independentUser->type, $allowPoolsType->toArray())) {
            $type = $independentUser->type;
        } else {
            $type = $user->game->is_novice == true ? $this->getNoviceType() : $this->getDefaultType();
        }
        $query = Model::query();
        $query->where('type', $type);
        if ($lock) {
            $query->lockForUpdate();
        }
        // $model = $fail ? $query->firstOrFail() : $query->first();
        $model = $query->first();
        if (!$model && $fail) {
            throw new BasicException(-1, '奖池缺少奖品');
        }
        return $model;
    }

    public function all(array $filters = [], int $page = 1, int $perPage = 15)
    {
        $query = Model::query();
        $query->where($filters);
        $models = $query->paginate($perPage, ['*'], 'page', $page);
        return $models;
    }

    public function one(array $filters, bool $fail = false)
    {
        $query = Model::query();
        $query->where($filters);
        $model = $fail ? $query->firstOrFail() : $query->first();
        return $model;
    }

    public function find(int $id)
    {
        $model = $this->one(['id' => $id], true);
        return $model;
    }

    public function create(array $data)
    {
        $model = new Model();
        $model->fill($data);
        $model->save();
        $model->refresh();

        return $model;
    }

    public function update(int $id, array $data)
    {
        $model = $this->find($id);
        $model->fill($data);
        $model->save();
        return $model;
    }
}
